package com.bs.visitservice.interceptor;

import com.auth0.jwt.interfaces.Claim;
import com.bs.visitservice.cache.impl.JedisLoginCache;
import com.bs.visitservice.common.SysException;
import com.bs.visitservice.utils.JwtUtil;
import com.bs.visitservice.utils.ParamUtils;
import com.bs.visitservice.utils.ThreadLocalUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用来对token进行验证，或获取相关信息
 */
@Component
public class TokenInterceptor implements HandlerInterceptor {
    @Autowired
    private JedisLoginCache jedisLoginCache;
    private Logger logger = LoggerFactory.getLogger(TokenInterceptor.class);
    //白名单，不需要tokenId验证
    private String[] whiteArr = new String[]{"/userpublic","/sellerpublic","/error","/adminpublic","/standardCode",
            "//userpublic","//sellerpublic","//error","//adminpublic","//standardCode","/message","//message"};
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if(!(handler instanceof HandlerMethod)){
            return true;
        }
        String requestUri = request.getRequestURI();
        int length = requestUri.length();
        logger.info(("requestUri:"+requestUri));
        String contextPath = request.getContextPath();
        logger.info(("contextPath:"+contextPath));
        requestUri = requestUri.substring(contextPath.length(),length);
        //白名单路径无需验证
        for(int i = 0;i<whiteArr.length;i++){
            if(requestUri.startsWith(whiteArr[i])){
                return true;
            }
        }

        //查看请求中是否有tokenId
        String tokenId = ParamUtils.getToken(request);
        if(tokenId == null){
            logger.info("无效请求,tokenId不存在");
            throw new SysException("无效请求,tokenId不存在","100");
        }
        //查看是否退出
        Object cache = jedisLoginCache.getCache(tokenId);
        if(cache == null){
            logger.info("tokenId失效，用户已退出！");
            throw new SysException("tokenId失效，用户已退出！","100");
        }
        //缓存中保存的是用户编号,现在保存到当前请求线程中，方便后面业务使用
        Long loginNo = Long.valueOf((Integer)cache);
        ThreadLocalUtil.put("loginNo",loginNo);
        //验证tokenId是否有效
        Map<String, Object> claims = JwtUtil.verifyToken(tokenId);
        Claim roleClaim = (Claim)claims.get("role");
        String role = roleClaim.asString();
        boolean checkPach = false;
        List<String> pathList  = getRolePath(role);
        if(pathList == null){
            throw new SysException("无权访问目标地址！","500");
        }
        for(String path: pathList){
            if(requestUri.startsWith(path)){
                checkPach = true;
            }
        }
        if(!checkPach){
            throw new SysException("无权访问目标地址！","500");
        }
        //如果tokenId有效，继续延长时间30分钟，测试时间加长
        jedisLoginCache.putCache(tokenId,loginNo,30*60*60);
        return true;
    }

    /**
     * 静态配置角色可访问地址
     * @param role
     * @return
     */
    private List<String> getRolePath(String role){
        Map<String,List> rolePath = new HashMap<>();
        List<String> sellerList =  new ArrayList<>();
        sellerList.add("/seller");
        sellerList.add("//seller");
        List<String> userList =  new ArrayList<>();
        userList.add("/user");
        userList.add("//user");
        List<String> adminList = new ArrayList<>();
        adminList.add("/admin");
        adminList.add("//admin");
        rolePath.put("seller",sellerList);
        rolePath.put("user",userList);
        rolePath.put("admin",adminList);
        return rolePath.get(role);
    }
}
